package io.seata.samples.sc.tccat.consumer.service;

import io.seata.samples.sc.tccat.api.model.User;
import io.seata.samples.sc.tccat.consumer.action.TccActionOne;
import io.seata.samples.sc.tccat.consumer.action.TccActionTwo;
import io.seata.samples.sc.tccat.consumer.feign.ActionDbFeign;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.seata.spring.annotation.GlobalTransactional;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * The type Tcc transaction service.
 *
 * @author lenovo
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class TccTransactionService {
    private final TccActionOne tccActionOne;
    private final TccActionTwo tccActionTwo;
    private final ActionDbFeign actionDbFeign;

    /**
     * 测试分布式事务提交示例
     *
     * @return string string
     */
    @GlobalTransactional
    public String testCommit() {
        // 第一个TCC 事务参与者
        String result = tccActionOne.prepare("action-one-commit").getMessage();
        // 第二个TCC 事务参与者
        result = result + "\n" + tccActionTwo.prepare("action-two-commit").getMessage();
        // 数据库操作
        actionDbFeign.saveOrUpdate(getUser());
        return result;
    }

    /**
     * 测试分布式事务回滚示例
     *
     * @return string string
     */
    @GlobalTransactional
    public String testRollback() {
        // 第一个TCC 事务参与者
        String result = tccActionOne.prepare("action-one-rollback").getMessage();
        // 第二个TCC 事务参与者
        result = result + "\n" + tccActionTwo.prepare("action-two-rollback").getMessage();
        // 数据库操作
        actionDbFeign.saveOrUpdate(getUser());
        throw new RuntimeException(result);
    }

    private User getUser() {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
        String format = formatter.format(LocalDateTime.now());
        User user = new User();
        user.setId(1L);
        user.setUsername("张三" + format);
        user.setPassword(format);
        user.setRealName("real:" + format);
        return user;
    }
}
